import re
import datetime
import urllib.parse

from Config import *
from OutputProperty import OutputProperty

StrDateFormat = "(\d{1,2})/(\d{1,2})/(\d{4})"
StrDateFormat2 = "(\d{4})/(\d{1,2})/(\d{1,2})"
StrDateFormat3 = "(\d{4})-(\d{2})-(\d{2})"

class MySQLGenerator():
    def __init__(self):
        self.__outputProperties = []

    def Generate(self, inputPath, outputPath):
        with open(inputPath, encoding = ENCODING) as f:
            for l in f.readlines():
                line = l.strip()
                if line == "":
                    continue
                self.__parse(line)
        with open(outputPath, "w", encoding = ENCODING) as f:
            f.write("use ej;\n")
            for p in self.__outputProperties:
                values = ",".join([str(p.Category.value), str(p.Currency.value), str(p.Amount), str(p.PayMethod.value), str(p.Owner.value), "\'" + p.Note + "\'", self.__dateToString(p.Datetime)])
                f.write("insert into bill (Category, Currency, Amount, PaymentMode, PID, Note, Datetime) values (" + values + ");\n")
                if p.Event != "":
                    for e in p.Event.split(INNER_SEPARATOR):
                        eventName = e.strip()
                        if eventName != "":
                            f.write("insert into mapbillfinanceevent (Bill, Event) values((select max(ID) from bill where PID=" + str(p.Owner.value) + "), (select ID from financeevent where Name=\'" + eventName + "\'));\n")

    def __dateToString(self, date):
        return "\'" + str(date.year) + "-" + str(date.month) + "-" + str(date.day) + "\'"

    def __parse(self, line):
        if not re.search(StrDateFormat, line) and not re.search(StrDateFormat2, line) and not re.search(StrDateFormat3, line):
            return
        items = line.split(SEPARATOR)
        prop = OutputProperty()
        prop.Owner = self.__getOwner(items[0].strip())
        prop.Datetime = self.__getDatetime(items[1].strip())
        prop.Amount = self.__getAmount(items[2].strip())
        prop.Currency = self.__getCurrency(items[3].strip())
        prop.Category = self.__getCategory(items[4].strip())
        prop.PayMethod = self.__getPayment(items[6].strip())
        prop.Note = self.__getNote(items[7].strip())
        prop.Event = self.__getEvent(items[8].strip()) if len(items) > 8 else ""
        self.__outputProperties.append(prop)

    def __getOwner(self, str):
        for o in Owner:
            if re.search(o.name, str):
                return o
        raise Exception("Wrong Owner", str)

    def __getDatetime(self, str):
        match = re.match(StrDateFormat, str)
        if match:
            return datetime.date(int(match.group(3)), int(match.group(1)), int(match.group(2)))
        match = re.match(StrDateFormat2, str)
        if match:
            return datetime.date(int(match.group(1)), int(match.group(2)), int(match.group(3)))
        match = re.match(StrDateFormat3, str)
        if match:
            return datetime.date(int(match.group(1)), int(match.group(2)), int(match.group(3)))
        raise Exception("Wrong Datetime", str)

    def __getAmount(self, str):
        return float(str)

    def __getCurrency(self, str):
        for c in Currency:
            if c.name == str:
                return c
        raise Exception("Wrong Currency", str)

    def __getCategory(self, str):
        for c in Category:
            if c.name == str:
                return c
        raise Exception("Wrong Category", str)

    def __getPayment(self, str):
        for p in PayMethod:
            if p.name == str:
                return p
        raise Exception("Wrong Payment", str)

    def __getNote(self, str):
        return urllib.parse.quote(str.replace("#", ";;::").replace("&", "::;;").replace("\"", "").replace("\'", ""))

    def __getEvent(self, str):
        return str
